local function copy_value(value)
    if type(value) ~= "table" then
        return value
    end
    local cpt = {}
    for k,v in pairs(value) do
        cpt[copy_value(k)] = copy_value(v)
    end

    return setmetatable(cpt,value)
end

local function merge(taba,tabb)
    if tabb == nil then
        return taba
    end
    for k,v in pairs(tabb) do
        if taba[k] == nil then
            taba[copy_value(k)] = copy_value(v)
        end
    end
    return taba
end 

local function class(name,...)
    local merges = {...}
    return function(class)
        class.__name__  = name
        class.__merge__ = merge
        class.__merges__ = {[class.__name__] = true}
        for k,cls in ipairs(merges) do
            class.__merges__[cls.__name__] = true
            merge(class.__merges__,cls.__merges__)
        end

        function class:__new__(...)
            local instance = {}
            self.__merge__(instance,self)
            if instance.__init__ then
                instance:__init__(...)
            end

            setmetatable(instance,instance)
            return instance
        end

        function class:reg(...)
            self.reg = nil
            oopsys.registered(class)
            if type(self.__reg__) == "function" then
                self:__reg__(...)
            end
            return self
        end

        --function class:__init__()end
        --function class:__reg__()end

        if #merges ~= 0 then
            for i,cls_or_comp in ipairs(merges) do
                class:__merge__(cls_or_comp)
            end
        end

        class.__call = class.__new__
        return setmetatable(class,class) 
    end
end

local function component(name,...)
    local merges = {...}
    return function(component)
        component.__name__  = name;
        component.__merge__ = merge;
        if #merges ~= 0 then
            for i,cls_or_comp in ipairs(merges) do
                component:__merge__(cls_or_comp)
            end
        end

        function component:reg(...)
            self.reg = nil
            oopsys.registered(self)
            if type(self.__reg__) == "function" then
                self:__reg__(...)
            end
            return self
        end

        --function component:__reg__()end

        return component
    end
end

return {
    class = class,
    component = component,
}
